package yang.VirtualMachine.chapter9.classStruct.constantPool;

import java.io.IOException;
import java.io.InputStream;

import yang.VirtualMachine.chapter9.ClassUtil;

/**
 * 常量池解析
 * 常量池存放字面量:字符串（方法中也算），常量，
 * int型除非是常量，否则不加入常量池（final 或者 static 都不行，方法里也不行）
 * 存放类，方法名，签名（参数与返回值类型）
 * 
 * CONSTANT_Utf8，CONSTANT_数字：
 * 	指向一个具体的内容，如字符串，数字的高低位等
 * CONSTANT_Methodref与CONSTANT_Fieldref与CONSTANT_InterfaceMethodref:
 * 	class_index,指向属性属于的类 (CONSTANT_Utf8)		name_and_type_index,指向CONSTANT_NameAndType
 * CONSTANT_NameAndType:
 * 	name_index,指向属性名 (CONSTANT_Utf8)
 *	descriptor_index指向类型 (CONSTANT_Utf8)
 *		属性则字符串表示类型(I,int s,short等)
 *		方法则字符串表示方法类型(例如:(I)V表示此方法输入int返回void)
 * @author xinxin
 */
public class ConstantPoolController {
	
	/** 字符串 	u1 tag;u2 length;		u1 bytes[length] */
	public static final int CONSTANT_Utf8 = 1;
	/** 整形 		u1 tag;u4 bytes */
	public static final int CONSTANT_Integer = 3;
	/** 浮点型 	u1 tag;u4 bytes */
	public static final int CONSTANT_Float = 4;
	/** Long 	u1 tag;u4 high_bytes;	u4 low_bytes; */
	public static final int CONSTANT_Long = 5;
	/** Double	u1 tag;u4 high_bytes;	u4 low_bytes; */
	public static final int CONSTANT_Double = 6;
	/** class u1 tag;u2 name_index;*/
	public static final int CONSTANT_Class = 7;
	/** String u1 tag;u2 string_index;*/
	public static final int CONSTANT_String = 8;
	/** 属性 u1 tag;u2 class_index;	u2 name_and_type_index */
	public static final int CONSTANT_Fieldref = 9;
	/** 方法	  u1 tag;u2 class_index;	u2 name_and_type_index */
	public static final int CONSTANT_Methodref = 10;
	/** 接口方法 u1 tag;u2 class_index;	u2 name_and_type_index */
	public static final int CONSTANT_InterfaceMethodref = 11;
	/** 类型:名字 u1 tag;u2 name_index;	u2 descriptor_index */
	public static final int CONSTANT_NameAndType = 12;
	
	/** ----------------------------JDK7以后加入-------------------------------------- */
	/** 类型:名字 u1 tag;u1 reference_kind	u2 reference_index */
	public static final int CONSTANT_MethodHandle = 15;
	/** 类型:名字 u1 tag;u2 descriptor_index */
	public static final int CONSTANT_MethodType = 16;
	/** 类型:名字 u1 tag;u2 bootstrap_method_attr_index	u2 name_and_type_index */
	public static final int CONSTANT_InvokeDynamic = 18;
	
	public static PoolValue processController(InputStream input) throws IOException {
		int tag = (int) ClassUtil.getNumByStream(input, 1);
		PoolValue processer;
		switch (tag) {
		case CONSTANT_Utf8:
			processer = new Con_Utf8Processer();
			break;
		case CONSTANT_Integer:
			processer = new Con_IntegerProcesser();
			break;
		case CONSTANT_Float:
			processer = new Con_FloatProcesser();
			break;
		case CONSTANT_Long:
			processer = new Con_LongProcesser();
			break;
		case CONSTANT_Class:
			processer = new Con_ClassProcesser();
			break;
		case CONSTANT_String:
			processer = new Con_StringProcesser();
			break;
		case CONSTANT_Fieldref:
			processer = new Con_FieldrefProcesser();
			break;
		case CONSTANT_Methodref:
			processer = new Con_MethodrefProcesser();
			break;
		case CONSTANT_InterfaceMethodref:
			processer = new Con_InterfaceMethodrefProcesser();
			break;
		case CONSTANT_NameAndType:
			processer = new Con_NameAndTypeProcesser();
			break;
		case CONSTANT_MethodHandle:
			processer = new Con_MethodHandleProcesser();
			break;
		case CONSTANT_MethodType:
			processer = new Con_MethodTypeProcesser();
			break;
		case CONSTANT_InvokeDynamic:
			processer = new Con_InvokeDynamicProcesser();
			break;
		default:
			return null;
		}

		processer.start(input);
		processer.process(input);
		processer.end(input);
		return processer;
	}

}
